﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Services;
using Microsoft.Xrm.Sdk.Query;

namespace MSCRMSolutionBackup
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if(args.Length != 1)
                {
                    throw new Exception("Connections string missing! e.g. 'Url=http://domain.com/org; Domain=myad; Username=myuser; Password=mypassword;'");
                }
                var backupfolder = DateTime.Now.ToString("yyyyMMdd");
                var connection = CrmConnection.Parse(args[0].ToString());
                connection.Timeout = new TimeSpan(0, 10, 0);
                var service = new OrganizationService(connection);

                var query = new QueryByAttribute("solution");
                query.ColumnSet = new ColumnSet(true);
                query.AddAttributeValue("ismanaged", false);
                query.AddAttributeValue("isvisible", true);
                var solutionList = service.RetrieveMultiple(query);

                if (solutionList.Entities.Count > 0)
                {
                    Directory.CreateDirectory(backupfolder);
                }

                foreach (var s in solutionList.Entities)
                {
                    try
                    {
                        var solutionName = s.GetAttributeValue<string>("uniquename");
                        Console.Write(string.Format("Downloading {0}...", solutionName));
                        var solution = (ExportSolutionResponse)service.Execute(new ExportSolutionRequest() { SolutionName = solutionName });
                        File.WriteAllBytes(string.Format(@"{0}\{1}.zip", backupfolder, solutionName), solution.ExportSolutionFile);
                        Console.WriteLine(" DONE!");
                    }
                    catch (Exception ex)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine(ex.Message);
                        Console.ResetColor();
                        log(string.Format("ERROR - {0}", ex.Message));
                    }
                }
            }
            catch(Exception ex)
            {
                Console.ForegroundColor=ConsoleColor.Red;
                Console.WriteLine(ex.Message);
                Console.ResetColor();
                log(string.Format("ERROR - {0}", ex.Message));
            }
        }

        private static void log(string message)
        {
            try
            {
                File.AppendAllText("MSCRMSolutionBackup.log", string.Format("{0} - {1}{2}", DateTime.Now.ToString("yyyyMMdd hh:mm:ss"), message, Environment.NewLine));
            }
            catch { }
        }
    }
}
